// 应用顶点颜色到网格
function applyVertexColors(mesh, color) {
  mesh.faces.forEach(function (face) {
    for (var vertexCount = face instanceof THREE.Face3 ? 3 : 4, i = 0; i < vertexCount; i++)
      face.vertexColors[i] = color;
  });
}

// 使对象始终面向相机
function changeObjFace(objects) {
  $.each(objects, function (index, object) {
    object.lookAt(camera.position);
  });
}

// 鼠标移动事件处理
function onMouseMove(event) {
  mouse.x = event.screenX;
  mouse.y = event.screenY;
}

// 拾取对象
function pick() {
  renderer.render(pickingScene, camera, pickingTexture);
  var pixelData = new Uint8Array(4);
  renderer.readRenderTargetPixels(pickingTexture, mouse.x, pickingTexture.height - mouse.y, 1, 1, pixelData);
  var pickedObject = pickingData[(pixelData[0] << 16) | (pixelData[1] << 8) | pixelData[2]];
  pickedObject
    ? pickedObject.position &&
      pickedObject.rotation &&
      pickedObject.scale &&
      (highlightBox.position.copy(pickedObject.position),
      highlightBox.rotation.copy(pickedObject.rotation),
      highlightBox.scale.copy(pickedObject.scale).add(offset),
      (highlightBox.visible = true))
    : (highlightBox.visible = false);
}

// 窗口大小调整事件处理
function onWindowResize() {
  renderer.setSize(window.innerWidth, window.innerHeight);
}

// 文档鼠标移动事件处理
function onDocumentMouseMove(event) {
  event.preventDefault();
  mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
  mouse.y = 2 * -(event.clientY / window.innerHeight) + 1;
  showAbstract(event.clientX, event.clientY);
}

// 鼠标点击事件处理
function onMouseClick(event) {
  INTERSECTED && isShowDetail && (showDetail(true), showPic(true));
}

// 显示摘要信息
function showAbstract(x, y) {
  if (INTERSECTED) {
    $("#abstract").css("display", "table");
    var abstractElement = document.getElementById("abstract");
    abstractElement.innerText = INTERSECTED.value;
    abstractElement.style.top = y + "px";
    abstractElement.style.left = x - 88 + "px";
  } else $("#abstract").css("display", "none");
}

// 全局变量：指向的对象、显示的字符串、图片路径
var pointed, showString, picPath;

// 显示文本内容
function showText(text) {
  $("#detail").html("<textarea></textarea>");
  $("#detail textarea").typetype(text, { t: 10, e: 0 });
}

// 显示详细信息
function showDetail(show) {
  show
    ? INTERSECTED.name != pointed &&
      ((showString = INTERSECTED.userData.abstract),
      $("#detail").slideDown(1000),
      $("#detail").html(
        '<div style="background-color: rgba(50,50,50,0.8);color: white;padding: 5px 5px 5px 5px;opacity: 0.7;border: 0;resize: none;font-size: 23px;text-align: center;padding-top: 58%;padding-bottom: 70%;">加载中...</div>'
      ),
      setTimeout("showText(showString)", 500))
    : $("#detail").slideUp(900);
}

// 更改图片
function changePic(picName) {
  $("#picture img").attr("src", "./pic/" + picName);
  $("#picture").fadeIn(400);
}

// 显示图片
function showPic(show) {
  show
    ? INTERSECTED.name != pointed &&
      ((picPath = INTERSECTED.userData.pic),
      $("#picture").fadeOut(400),
      setTimeout("changePic(picPath)", 400),
      (pointed = INTERSECTED.name))
    : $("#picture").fadeOut(900);
}

// 射线检测鼠标移动
function rayMousemove(mousePosition, camera) {
  raycaster.setFromCamera(mousePosition, camera);
  var intersects = raycaster.intersectObjects(nodeObjects);
  if (intersects.length > 0) {
    if (INTERSECTED != intersects[0].object) {
      if (INTERSECTED) {
        INTERSECTED.material.emissive.setHex(INTERSECTED.currentHex);
      }
      INTERSECTED = intersects[0].object;
      INTERSECTED.currentHex = INTERSECTED.material.emissive.getHex();
      INTERSECTED.scale.setScalar(1.2);
      INTERSECTED.material.emissive.setHex(5592405);
      console.log(INTERSECTED.name);
    }
  } else {
    if (INTERSECTED) {
      INTERSECTED.material.emissive.setHex(INTERSECTED.currentHex);
      INTERSECTED.scale.setScalar(1);
    }
    INTERSECTED = null;
  }
}

// 对节点和连接进行排序
function node_link_Sort(data) {
  var sortedData = [];
  for (var i = 1; i < 4; i++) {
    $.each(data, function (index, item) {
      if (item.layer == i) sortedData.push(item);
    });
  }
  return sortedData;
}

// 休眠函数
function sleep(duration) {
  var startTime = new Date();
  for (var endTime = startTime.getTime() + duration; !((startTime = new Date()), startTime.getTime() > endTime); );
}

// 获取力导向布局
function getForceLayout(nodes, links) {
  var nodeList = [],
    linkList = [];
  $.each(nodes, function (index, node) {
    nodeList.push({
      name: node.id,
      value: node.name,
      path: node.path,
      layer: node.layer,
      abstract: node.abstract,
      pic: node.pic,
      position: {
        x: node.x || 0.1,
        y: node.y || 0.1,
      },
    });
  });
  linkList = links;
  for (var i = 1; i < 4; i++) {
    var layerData = { nodes: [], links: [] };
    $.each(nodeList, function (index, node) {
      if (node.layer == i) layerData.nodes.push(node);
    });
    $.each(linkList, function (index, link) {
      if (link.layer == i) layerData.links.push(link);
    });
    FORCE.getForceLayout(layerData, function (positions, b) {
      $.each(layerData.nodes, function (index, node) {
        node.position = {
          x: node.position.x || positions[index].p[0] - 500,
          y: node.position.y || 500 - positions[index].p[1],
        };
      });
      console.log(layerData);
    });
  }
  return nodeList;
}

// 全局变量：容器、性能监控、相机、控制器、场景、渲染器、射线检测器、节点对象数组、网络组、节点位置数组、JSON数据、是否显示详细信息、鼠标位置、当前相交对象、半径、角度、偏移量
var container,
  stats,
  camera,
  controls,
  scene,
  renderer,
  raycaster,
  nodeObjects = [],
  networkGroup = new THREE.Group(),
  nodePos = [],
  jsonData,
  isShowDetail = !0,
  mouse = new THREE.Vector2(),
  INTERSECTED = false,
  radius = 100,
  theta = 0,
  offset = new THREE.Vector3(10, 10, 10);
function updateConnectingLines() {
  // 移除旧连接线
  networkGroup.children.forEach((group) => {
    const arrows = group.children.filter((child) => child instanceof THREE.ArrowHelper);
    arrows.forEach((arrow) => group.remove(arrow));
  });

  // 重建连接线
  jsonData.links.forEach((link) => {
    const sourceNode = nodeObjects.find((n) => n.name === link.source);
    const targetNode = nodeObjects.find((n) => n.name === link.target);
    if (sourceNode && targetNode) {
      const direction = new THREE.Vector3().subVectors(targetNode.position, sourceNode.position).normalize();
      const arrow = new THREE.ArrowHelper(
        direction,
        sourceNode.position,
        sourceNode.position.distanceTo(targetNode.position) - 25,
        "yellow",
        20,
        7
      );
      networkGroup.children[link.layer - 1].add(arrow);
    }
  });
}

function startAutoMovement() {
  let direction = 1;
  let moving = false;

  // 存储原始位置用于计算偏移量
  const originalPositions = new Map();
  nodeObjects.forEach((node) => {
    originalPositions.set(node.name, node.position.clone());
  });

  setInterval(() => {
    if (moving) return;
    moving = true;

    // 计算目标位置
    const targetPositions = new Map();
    nodeObjects.forEach((node) => {
      const nodeData = jsonData.nodes.find((n) => n.id === node.name);
      if (nodeData && nodeData.layer === 2) {
        targetPositions.set(
          node.name,
          new THREE.Vector3(node.position.x + 50 * direction, node.position.y, node.position.z)
        );
      }
    });

    // 创建动画
    new TWEEN.Tween({ progress: 0 })
      .to({ progress: 1 }, 1000)
      .onUpdate(function () {
        // 同时更新节点和连接线
        nodeObjects.forEach((node) => {
          if (targetPositions.has(node.name)) {
            const originalPos = originalPositions.get(node.name);
            const targetPos = targetPositions.get(node.name);
            node.position.lerpVectors(originalPos, targetPos, this.progress);
          }
        });
        updateConnectingLines(); // 每帧更新连接线
      })
      .onComplete(() => {
        direction *= -1;
        moving = false;
        // 更新原始位置记录
        nodeObjects.forEach((node) => {
          if (targetPositions.has(node.name)) {
            originalPositions.set(node.name, node.position.clone());
          }
        });
      })
      .start();
  }, 3000);
}
// 存储所有 JSON 文件路径
const jsonFiles = [
  "js/data/satellite-csv/json/satellite-topology-1.json",
  "js/data/satellite-csv/json/satellite-topology-2.json",
  "js/data/satellite-csv/json/satellite-topology-3.json",
  "js/data/satellite-csv/json/satellite-topology-4.json",
  "js/data/satellite-csv/json/satellite-topology-5.json",
  "js/data/satellite-csv/json/satellite-topology-6.json",
  "js/data/satellite-csv/json/satellite-topology-7.json",
  "js/data/satellite-csv/json/satellite-topology-8.json",
  "js/data/satellite-csv/json/satellite-topology-9.json",
  "js/data/satellite-csv/json/satellite-topology-10.json",
  "js/data/satellite-csv/json/satellite-topology-11.json",
  "js/data/satellite-csv/json/satellite-topology-12.json",
  "js/data/satellite-csv/json/satellite-topology-13.json",
  "js/data/satellite-csv/json/satellite-topology-14.json",
  "js/data/satellite-csv/json/satellite-topology-15.json",
  // "js/data/satellite-csv/json/satellite-topology-16.json",
  // "js/data/satellite-csv/json/satellite-topology-17.json",
  // "js/data/satellite-csv/json/satellite-topology-18.json",
  // "js/data/satellite-csv/json/satellite-topology-19.json",
  // "js/data/satellite-csv/json/satellite-topology-20.json",
  // "js/data/satellite-csv/json/satellite-topology-21.json",
  // "js/data/satellite-csv/json/satellite-topology-22.json",
];

let currentIndex = 0;

// 加载新数据并创建过渡动画
function loadNewData() {
  $.getJSON(jsonFiles[currentIndex], function (newData) {
    // 存储当前节点位置
    const currentPositions = nodeObjects.map((node) => node.position.clone());

    // 处理新节点数据
    const newNodes = newData.nodes;
    const newLinks = newData.links;

    // 更新节点位置的过渡动画
    new TWEEN.Tween({ progress: 0 })
      .to({ progress: 1 }, 2000)
      .onUpdate(function () {
        newNodes.forEach((newNode, index) => {
          const node = nodeObjects.find((n) => n.name === newNode.id);
          if (node) {
            const targetPos = new THREE.Vector3(newNode.x, 320 - 300 * (newNode.layer - 1), newNode.y);
            node.position.lerpVectors(currentPositions[index], targetPos, this.progress);
          }
        });
        if (currentIndex !== 0) updateConnectingLines(); // 每帧更新连接线
        else {
          networkGroup.children.forEach((group) => {
            const arrows = group.children.filter((child) => child instanceof THREE.ArrowHelper);
            arrows.forEach((arrow) => group.remove(arrow));
          });
        }
      })
      .onComplete(() => {
        // 更新链接数据
        jsonData.links = newLinks;
        updateConnectingLines();

        // 循环到下一个 JSON 文件
        currentIndex = (currentIndex + 1) % jsonFiles.length;
        setTimeout(loadNewData, 0);
      })
      .start();
  });
}

// 加载 CSV 文件并更新表格
function loadCSVAndUpdateTable() {
  $.ajax({
    url: "js/data/satellite-csv/output1.csv",
    dataType: "text",
    success: function (csvData) {
      const rows = csvData.split("\n"); // 最多取 8 行
      const tbody = $("#detail1 tbody");
      tbody.empty(); // 清空现有内容

      rows.forEach((row, index) => {
        const columns = row.split(",");
        if (columns.length === 3) {
          const tr = $("<tr>");
          tr.append($("<td>").text(`${index + 1}`));
          tr.append($("<td>").text(columns[0]));
          tr.append($("<td>").text(columns[1]));
          tr.append($("<td>").text(columns[2]));
          tbody.append(tr);
        }
      });

      // 添加滚动逻辑
      startTableScroll("#detail1");
    },
  });

  $.ajax({
    url: "js/data/satellite-csv/output2.csv",
    dataType: "text",
    success: function (csvData) {
      const rows = csvData.split("\n"); // 最多取 8 行
      const tbody = $("#detail2 tbody");
      tbody.empty(); // 清空现有内容

      rows.forEach((row, index) => {
        const columns = row.split(",");
        if (columns.length === 4) {
          const tr = $("<tr>");
          tr.append($("<td>").text(`${index + 1}`));
          tr.append($("<td>").text(columns[0]));
          tr.append($("<td>").text(columns[1]));
          tr.append($("<td>").text(columns[2]));
          tr.append($("<td>").text(columns[3]));
          tbody.append(tr);
        }
      });

      // 添加滚动逻辑
      startTableScroll("#detail2");
    },
  });
}

// 启动表格滚动
function startTableScroll(tableId) {
  const table = $(tableId);
  const tbody = table.find("tbody");
  const rowHeight = tbody.find("tr:first").outerHeight();

  setInterval(() => {
    tbody.animate(
      {
        scrollTop: `+=${rowHeight}`,
      },
      500,
      () => {
        const firstRow = tbody.find("tr:first");
        tbody.append(firstRow);
        tbody.scrollTop(0);
      }
    );
  }, 1000);
}
$().ready(function () {
  $.getJSON(jsonFiles[currentIndex], function (a) {
    jsonData = a;
    init();
    animate();
    setTimeout(loadNewData, 0);
    // 显示 detail1 和 detail2
    $("#detail1").show();
    $("#detail2").show();

    // 加载 CSV 并更新表格
    loadCSVAndUpdateTable();
  });
});
function init() {
  // 获取容器元素
  container = document.getElementById("container");

  // 创建透视相机
  camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 1, 4e3);
  camera.position.set(0, 740, 1000);

  // 初始化轨道控制器
  controls = new THREE.OrbitControls(camera);
  controls.rotateSpeed = 1;
  controls.zoomSpeed = 1.2;
  controls.panSpeed = 0.8;
  controls.enableZoom = true;
  controls.enablePan = false;
  controls.autoRotate = false;
  controls.autoRotateSpeed = 0.5;

  // 创建场景
  scene = new THREE.Scene();
  scene.background = new THREE.Color(0);

  // 添加环境光
  scene.add(new THREE.AmbientLight(16777215));

  // 创建网格组并添加网格辅助线
  var planeGroup = new THREE.Group();
  var gridHeight;
  for (var layerIndex = 0; layerIndex < 3; layerIndex++) {
    if (layerIndex === 2) {
      // 第三层替换为图片
      var texture = new THREE.TextureLoader().load("./pic/earth.png");
      var planeGeometry = new THREE.PlaneGeometry(1600, 1050);
      var planeMaterial = new THREE.MeshBasicMaterial({
        map: texture,
        side: THREE.DoubleSide,
        transparent: true,
      });
      var plane = new THREE.Mesh(planeGeometry, planeMaterial);
      gridHeight = 300 - 300 * layerIndex;
      plane.position.y = gridHeight;
      plane.rotation.x = -Math.PI / 2; // 水平放置
      planeGroup.add(plane);
    } else {
      gridHeight = 300 - 300 * layerIndex;
      var grid = new THREE.GridHelper(1050, 50);
      grid.position.y = gridHeight;
      grid.material.opacity = 0.75;
      grid.material.transparent = true;
      if (layerIndex == 0) grid.material.color = new THREE.Color("rgb(240, 134, 82)");
      if (layerIndex == 1) grid.material.color = new THREE.Color("rgb(122, 225, 116)");
      planeGroup.add(grid);
    }
  }
  planeGroup.name = "planeGroup";

  // 创建节点组
  var nodeGroup = new THREE.Group();
  nodeGroup.name = "nodeGroup";

  // 处理节点数据并创建节点对象
  var sortedNodes = node_link_Sort(jsonData.nodes);
  var sortedLinks = node_link_Sort(jsonData.links);
  var layoutData = getForceLayout(sortedNodes, sortedLinks);

  for (var layerIndex = 0; layerIndex < 3; layerIndex++) {
    var layerGroup = new THREE.Group();
    layerGroup.name = "第" + (layerIndex + 1) + "层";
    var nodeHeight = 320 - 300 * layerIndex;

    $.each(layoutData, function (index, nodeData) {
      if (nodeData.layer < layerIndex + 2) {
        if (nodeData.layer == layerIndex + 1) {
          var texture = new THREE.TextureLoader().load("./pic/" + nodeData.path);
          var nodeMesh = new THREE.Mesh(
            new THREE.PlaneGeometry(80, 80),
            new THREE.MeshPhongMaterial({
              transparent: true,
              opacity: 1,
              alphaTest: 0.5,
              emissive: 0x000000,
              side: THREE.DoubleSide,
            })
          );
          nodeMesh.position.set(nodeData.position.x, nodeHeight, nodeData.position.y);
          nodeMesh.value = nodeData.value;
          nodeMesh.name = nodeData.name;
          nodeMesh.userData.abstract = nodeData.abstract;
          nodeMesh.userData.pic = nodeData.pic;
          texture.magFilter = THREE.LinearFilter;
          texture.anisotropy = 2;
          nodeMesh.material.map = texture;
          nodePos.push({ position: nodeMesh.position, id: nodeData.id });
          nodeObjects.push(nodeMesh);
          layerGroup.add(nodeMesh);
        }
        return true;
      }
      return false;
    });
    nodeGroup.add(layerGroup);
  }

  // 创建连接线组
  var linkGroupLayer1 = new THREE.Group();
  var linkGroupLayer2 = new THREE.Group();
  var linkGroupLayer3 = new THREE.Group();
  var linkGroupLayer4 = new THREE.Group();

  // 处理连接数据并创建箭头辅助线
  for (var linkIndex = 0; linkIndex < jsonData.links.length; linkIndex++) {
    var link = jsonData.links[linkIndex];
    var sourcePosition = new THREE.Vector3();
    var targetPosition = new THREE.Vector3();
    var directionVector = new THREE.Vector3();

    $.each(sortedNodes, function (index, node) {
      if (node.id == link.source) {
        sourcePosition = nodePos[index].position;
      }
      if (node.id == link.target) {
        targetPosition = nodePos[index].position;
      }
    });

    directionVector.subVectors(targetPosition, sourcePosition);
    directionVector.normalize();
    var distance = sourcePosition.distanceTo(targetPosition);
    var arrow = new THREE.ArrowHelper(directionVector, sourcePosition, distance, "yellow", 1, 1);
    arrow.name = link.layer;

    switch (link.layer) {
      case 1:
        linkGroupLayer1.add(arrow);
        break;
      case 2:
        linkGroupLayer2.add(arrow);
        break;
      case 3:
        linkGroupLayer3.add(arrow);
        break;
      case 4:
        linkGroupLayer4.add(arrow);
    }
  }

  // 将节点、网格和连接线组合并到网络组中
  for (var layerIndex = 0; layerIndex < 3; layerIndex++) {
    var networkLayerGroup = new THREE.Group();
    networkLayerGroup.add(nodeGroup.children[0]);
    networkLayerGroup.add(planeGroup.children[0]);

    switch (layerIndex) {
      case 0:
        networkLayerGroup.add(linkGroupLayer1);
        break;
      case 1:
        networkLayerGroup.add(linkGroupLayer2);
        break;
      case 2:
        networkLayerGroup.add(linkGroupLayer3);
    }
    networkGroup.add(networkLayerGroup);
  }
  networkGroup.add(linkGroupLayer4);

  // 将网络组添加到场景中
  scene.add(networkGroup);

  // 创建WebGL渲染器
  renderer = new THREE.WebGLRenderer({ antialias: true });
  renderer.setPixelRatio(window.devicePixelRatio);
  renderer.setSize(window.innerWidth, window.innerHeight);
  renderer.domElement.style.height = "100%";
  renderer.domElement.style.width = "100%";
  container.appendChild(renderer.domElement);

  // 初始化射线检测器
  raycaster = new THREE.Raycaster();

  // 初始化性能监控
  stats = new Stats();

  // 添加事件监听器
  document.addEventListener("mousemove", onDocumentMouseMove, false);
  document.addEventListener("click", onMouseClick, false);
  window.addEventListener("resize", onWindowResize, false);

  // 启动自动移动
  // startAutoMovement();
}
// 全局变量：动画状态
var isAnimationPaused = false;

// 动画循环函数
function animate() {
  requestAnimationFrame(animate); // 请求下一帧动画
  if (!isAnimationPaused) {
    TWEEN.update(); // 更新 Tween 动画，这行必须存在！
  }
  render(); // 调用渲染函数
}

// 渲染函数
function render() {
  controls.update(); // 更新轨道控制器
  rayMousemove(mouse, camera); // 处理鼠标移动的射线检测
  changeObjFace(nodeObjects); // 使对象始终面向相机
  renderer.render(scene, camera); // 渲染场景
  // console.log(camera.position)
}

// 按钮点击事件绑定
$(".btn_list button").bind("click", function (event) {
  switch (event.target.id) {
    case "main": // 主按钮
      homeAnimation(); // 执行主页面动画
      break;
    case "upper": // 上层按钮
      networkAnimation(); // 执行网络层动画
      break;
    case "middle": // 中层按钮
      serviceAnimation(); // 执行服务层动画
      break;
    case "bottom": // 下层按钮
      virtualUser(); // 执行虚拟用户层动画
      break;
    case "browse": // 浏览按钮
      rotate(); // 切换自动旋转
      break;
    case "move": // 动画暂停/开始按钮
      isAnimationPaused = !isAnimationPaused;
      $(this).text(isAnimationPaused ? "动画开始" : "动画暂停");
      break;
  }
});

// 当前显示的层级
var which_layer = "home";

// 网络层动画
function networkAnimation() {
  isShowDetail = true; // 允许显示详细信息
  showDetail(false); // 隐藏详细信息
  showPic(false); // 隐藏图片
  if ("first" != which_layer) {
    // 如果当前不是第一层
    which_layer = "first"; // 设置当前层级为第一层
    TWEEN.removeAll(); // 移除所有 Tween 动画
    networkGroup.children[3].visible = false; // 隐藏第四层（连接线组）

    // 创建位置、缩放和旋转的 Tween 动画
    var positionTween = new TWEEN.Tween(networkGroup.children[0].position)
      .easing(TWEEN.Easing.Quadratic.Out) // 使用二次缓动
      .delay(100) // 延迟 100ms
      .to({ x: 0, y: -500, z: 0 }, 1000); // 目标位置

    var scaleTween = new TWEEN.Tween(networkGroup.children[0].scale)
      .delay(0) // 无延迟
      .easing(TWEEN.Easing.Exponential.Out) // 使用指数缓动
      .to({ x: 1.7, y: 1.7, z: 1.7 }, 5000); // 目标缩放

    var rotationTween = new TWEEN.Tween(networkGroup.children[0].rotation)
      .easing(TWEEN.Easing.Quadratic.Out) // 使用二次缓动
      .delay(100) // 延迟 100ms
      .to({ x: 0, y: 0, z: 0 }, 1000); // 目标旋转

    // 对每个子组执行缩放动画
    $.each(networkGroup.children, function (index, group) {
      new TWEEN.Tween(group.scale)
        .to({ x: 0.3, y: 0.3, z: 0.3 }, 800) // 目标缩放
        .easing(TWEEN.Easing.Quintic.InOut) // 使用五次缓动
        .start() // 启动动画
        .onComplete(function () {
          // 动画完成后
          positionTween.start(); // 启动位置动画
          scaleTween.start(); // 启动缩放动画
          rotationTween.start(); // 启动旋转动画
        });
    });

    // 对其他层执行位置和旋转动画
    new TWEEN.Tween(networkGroup.children[1].position)
      .delay(50) // 延迟 50ms
      .to({ y: 0, x: 1300, z: 0 }, 1000) // 目标位置
      .easing(TWEEN.Easing.Exponential.InOut) // 使用指数缓动
      .start(); // 启动动画

    new TWEEN.Tween(networkGroup.children[1].rotation)
      .delay(50) // 延迟 50ms
      .to({ y: 10, x: 0, z: 0 }, 3000) // 目标旋转
      .easing(TWEEN.Easing.Exponential.Out) // 使用指数缓动
      .start(); // 启动动画

    new TWEEN.Tween(networkGroup.children[2].position)
      .delay(50) // 延迟 50ms
      .to({ y: 0, x: -1300, z: 0 }, 1000) // 目标位置
      .easing(TWEEN.Easing.Exponential.InOut) // 使用指数缓动
      .start(); // 启动动画

    new TWEEN.Tween(networkGroup.children[2].rotation)
      .delay(50) // 延迟 50ms
      .to({ y: 10, x: 0, z: 0 }, 3000) // 目标旋转
      .easing(TWEEN.Easing.Exponential.Out) // 使用指数缓动
      .start(); // 启动动画
  }
}

// 服务层动画
function serviceAnimation() {
  isShowDetail = true; // 允许显示详细信息
  showDetail(false); // 隐藏详细信息
  showPic(false); // 隐藏图片
  if ("second" != which_layer) {
    // 如果当前不是第二层
    which_layer = "second"; // 设置当前层级为第二层
    TWEEN.removeAll(); // 移除所有 Tween 动画
    networkGroup.children[3].visible = false; // 隐藏第四层（连接线组）

    // 创建缩放、位置和旋转的 Tween 动画
    var scaleTween = new TWEEN.Tween(networkGroup.children[1].scale)
      .easing(TWEEN.Easing.Exponential.Out) // 使用指数缓动
      .delay(0) // 无延迟
      .to({ x: 1.7, y: 1.7, z: 1.7 }, 5000); // 目标缩放

    var positionTween = new TWEEN.Tween(networkGroup.children[1].position)
      .easing(TWEEN.Easing.Quadratic.Out) // 使用二次缓动
      .delay(100) // 延迟 100ms
      .to({ x: 0, y: 0, z: 0 }, 1000); // 目标位置

    var rotationTween = new TWEEN.Tween(networkGroup.children[1].rotation)
      .easing(TWEEN.Easing.Quadratic.Out) // 使用二次缓动
      .delay(100) // 延迟 100ms
      .to({ x: 极, y: 0, z: 0 }, 1000); // 目标旋转

    // 对每个子组执行缩放动画
    $.each(networkGroup.children, function (index, group) {
      new TWEEN.Tween(group.scale)
        .to({ x: 0.3, y: 0.3, z: 0.3 }, 800) // 目标缩放
        .easing(TWEEN.Easing.Quintic.InOut) // 使用五次缓动
        .start() // 启动动画
        .onComplete(function () {
          // 动画完成后
          scaleTween.start(); // 启动缩放动画
          positionTween.start(); // 启动位置动画
          rotationTween.start(); // 启动旋转动画
        });
    });

    // 对其他层执行位置和旋转动画
    new TWEEN.Tween(n极workGroup.children[0].position)
      .delay(100) // 延迟 100ms
      .to({ y: 0, x: 1300, z: 0 }, 2000) // 目标位置
      .easing(TWEEN.Easing.Exponential.InOut) // 使用指数缓动
      .start(); // 启动动画

    new TWEEN.Tween(networkGroup.children[0].rotation)
      .delay(100) // 延迟 100ms
      .to({ x: 0, y: 10, z: 0 }, 6000) // 目标旋转
      .easing(TWEEN.Easing.Exponential.Out) // 使用指数缓动
      .start(); // 启动动画

    new TWEEN.Tween(networkGroup.children[2].position)
      .delay(50) // 延迟 50ms
      .to({ y: 0, x: -1300, z: 0 }, 1000) // 目标位置
      .easing(TWEEN.Easing.Exponential.InOut) // 使用指数缓动
      .start(); // 启动动画

    new TWEEN.Tween(networkGroup.children[2].rotation)
      .delay(50) // 延迟 50ms
      .to({ y: 10, x: 0, z: 0 }, 3000) // 目标旋转
      .easing(TWEEN.Easing.Exponential.Out) // 使用指数缓动
      .start(); // 启动动画
  }
}

// 虚拟用户层动画
function virtualUser() {
  isShowDetail = true; // 允许显示详细信息
  showDetail(false); // 隐藏详细信息
  showPic(false); // 隐藏图片
  if ("third" != which_layer) {
    // 如果当前不是第三层
    which_layer = "third"; // 设置当前层级为第三层
    TWEEN.removeAll(); // 移除所有 Tween 动画
    networkGroup.children[3].visible = false; // 隐藏第四层（连接线组）

    // 创建位置、缩放和旋转的 Tween 动画
    var positionTween = new TWEEN.Tween(networkGroup.children[2].position)
      .easing(TWEEN.Easing.Quadratic.Out) // 使用二次缓动
      .delay(100) // 延迟 100ms
      .to({ x: 0, y: 500, z: 极 }, 1000); // 目标位置

    var scaleTween = new TWEEN.Tween(networkGroup.children[2].scale)
      .easing(TWEEN.Easing.Exponential.Out) // 使用指数缓动
      .delay(0) // 无延迟
      .to({ x: 1.7, y: 1.7, z: 1.7 }, 5000); // 目标缩放

    var rotationTween = new TWEEN.Tween(networkGroup.children[2].rotation)
      .easing(TWEEN.Easing.Quadratic.Out) // 使用二次缓动
      .delay(100) // 延迟 100ms
      .to({ x: 0, y: 0, z: 0 }, 1000); // 目标旋转

    // 对每个子组执行缩放动画
    $.each(networkGroup.children, function (index, group) {
      new TWEEN.Tween(group.scale)
        .to({ x: 0.3, y: 0.3, z: 0.3 }, 800) // 目标缩放
        .easing(TWEEN.Easing.Quintic.InOut) // 使用五次缓动
        .start() // 启动动画
        .onComplete(function () {
          // 动画完成后
          positionTween.start(); // 启动位置动画
          scaleTween.start(); // 启动缩放动画
          rotationTween.start(); // 启动旋转动画
        });
    });

    // 对其他层执行位置和旋转动画
    new TWEEN.Tween(networkGroup.children[0].position)
      .delay(100) // 延迟 100ms
      .to({ y: 0, x: 1300, z: 0 }, 2000) // 目标位置
      .easing(TWEEN.Easing.Exponential.InOut) // 使用指数缓动
      .start(); // 启动动画

    new TWEEN.Tween(networkGroup.children[0].rotation)
      .delay(100) // 延迟 100ms
      .to({ y: 10, x: 0, z: 0 }, 6000) // 目标旋转
      .easing(TWEEN.Easing.Exponential.Out) // 使用指数缓动
      .start(); // 启动动画

    new TWEEN.Tween(networkGroup.children[1].position)
      .delay(100) // 延迟 100ms
      .to({ y: 0, x: -1300, z: 0 }, 2000) // 目标位置
      .easing(TWEEN.Easing.Exponential.InOut) // 使用指数缓动
      .start(); // 启动动画

    new TWEEN.Tween(networkGroup.children[1].rotation)
      .delay(50) // 延迟 50ms
      .to({ y: 10, x: 0, z: 0 }, 3000) // 目标旋转
      .easing(TWEEN.Easing.Exponential.Out) // 使用指数缓动
      .start(); // 启动动画
  }
}

// 主页面动画
function homeAnimation() {
  // 箭头渐显动画
  function fadeInArrows() {
    $.each(arrowGroup.children, function (index, arrow) {
      var lineMaterial = arrow.line.material; // 获取箭头的线材质
      var coneMaterial = arrow.cone.material; // 获取箭头的锥体材质
      lineMaterial.transparent = true; // 设置线材质为透明
      coneMaterial.transparent = true; // 设置锥体材质为透明
      arrowGroup.visible = true; // 显示箭头组
      lineMaterial.opacity = 0.2; // 设置线材质初始透明度
      coneMaterial.opacity = 0.2; // 设置锥体材质初始透明度
      new TWEEN.Tween(lineMaterial).delay(0).to({ opacity: 1 }, 5000).easing(TWEEN.Easing.Exponential.Out).start(); // 线材质渐显动画
      new TWEEN.Tween(coneMaterial).delay(0).to({ opacity: 1 }, 5000).easing(TWEEN.Easing.Exponential.Out).start(); // 锥体材质渐显动画
    });
  }

  which_layer = "home"; // 设置当前层级为主页面
  isShowDetail = true; // 允许显示详细信息
  showDetail(false); // 隐藏详细信息
  showPic(false); // 隐藏图片
  TWEEN.removeAll(); // 移除所有 Tween 动画

  // 对每个子组执行缩放动画
  $.each(networkGroup.children, function (index, group) {
    new TWEEN.Tween(group.scale).to({ x: 1, y: 1, z: 1 }, 800).start(); // 目标缩放
  });

  var arrowGroup = networkGroup.children[3]; // 获取箭头组

  // 对其他层执行位置和旋转动画
  new TWEEN.Tween(networkGroup.children[0].position)
    .delay(0) // 无延迟
    .to({ y: 0, x: 0, z: 0 }, 700) // 目标位置
    .easing(TWEEN.Easing.Exponential.In) // 使用指数缓动
    .start(); // 启动动画

  new TWEEN.Tween(networkGroup.children[0].rotation)
    .delay(0) // 无延迟
    .to({ y: 0 }, 2500) // 目标旋转
    .easing(TWEEN.Easing.Quintic.Out) // 使用五次缓动
    .start(); // 启动动画

  new TWEEN.Tween(networkGroup.children[1].position)
    .delay(0) // 无延迟
    .to({ y: 0, x: 0, z: 0 }, 700) // 目标位置
    .easing(TWEEN.Easing.Exponential.In) // 使用指数缓动
    .start(); // 启动动画

  new TWEEN.Tween(networkGroup.children[1].rotation)
    .delay(0) // 无延迟
    .to({ y: 0 }, 2500) // 目标旋转
    .easing(TWEEN.Easing.Quintic.Out) // 使用五次缓动
    .start(); // 启动动画

  new TWEEN.Tween(networkGroup.children[2].position)
    .delay(0) // 无延迟
    .to({ y: 0, x: 0, z: 0 }, 700) // 目标位置
    .easing(TWEEN.Easing.Exponential.In) // 使用指数缓动
    .start(); // 启动动画

  new TWEEN.Tween(networkGroup.children[2].rotation)
    .delay(0) // 无延迟
    .to({ y: 0 }, 2500) // 目标旋转
    .easing(TWEEN.Easing.Quintic.Out) // 使用五次缓动
    .start() // 启动动画
    .onComplete(function () {
      // 动画完成后
      fadeInArrows(); // 执行箭头渐显动画
      IsHome = true; // 设置主页标志为 true
    });
}

// 切换自动旋转
function rotate() {
  controls.autoRotate = !controls.autoRotate; // 切换自动旋转状态
}
